home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-10 | 9.6 KB | 369 lines | [TEXT/PJMM] |
- {****************************************************}
- {}
- { CShLevelsDoc.p }
- {}
- { Document class for the Showwit! application. Documents store levels }
- { which can be played. }
- {}
- {****************************************************}
-
-
- unit CShLevelsDoc;
-
- interface
-
- uses
- TCL, ShIntf;
-
- implementation
-
-
- {****************************************************}
- {}
- { IShLevelsDoc }
- {}
- { Construction of the levels document object. }
- {}
- {****************************************************}
-
- procedure CShLevelsDoc.IShLevelsDoc (aSupervisor: CShApp);
-
- begin { IShLevelsDoc }
- itsShApp := aSupervisor;
-
- { We store our own pointer to the file, which we know to be of type CResFile. }
-
- itsShLevelsFile := nil;
-
- itsProgBar := nil;
-
- IDocument(aSupervisor, kNotPrintable);
- end; { IShLevelsDoc }
-
-
- {****************************************************}
- {}
- { Free }
- {}
- { Destruction of the levels document object. We set our pointers to nil, for the }
- { objects to which they were pointing will be disposed of in inherited methods. }
- {}
- {****************************************************}
-
- procedure CShLevelsDoc.Free;
-
- begin { Free }
- itsShApp := nil;
- itsShLevelsFile := nil;
-
- itsProgBar := nil;
-
- inherited Free;
- end; { Free }
-
-
- {****************************************************}
- {}
- { OpenFile }
- {}
- { Opens the levels file, reads the levels and then closes the document (we do }
- { not need the file open afterwards). Updates the progress bar whilst doing so. }
- {}
- {****************************************************}
-
- procedure CShLevelsDoc.OpenFile (macSFReply: SFReply);
-
- var
- theFile: CResFile;
-
- theList: CList;
- theLevel: CShLevel;
- theCount, theNumLevels: Integer;
-
- theSavedRes: Integer;
- fi: FailInfo;
-
- procedure BuildWindow;
-
- var
- theWindow: CWindow;
- theWindRect: Rect;
-
- thePicture: CPicture;
-
- theReadingStr: Str255;
- theEditText: CEditText;
-
- theProgBar: CProgressBar;
-
- theBorder: CPaneBorder;
-
- begin { BuildWindow }
- new(theWindow);
- theWindow.IWindow(WINDReader, kNotFloating, gDesktop, SELF);
- itsWindow := theWindow;
-
- { We don't want the window to be re-sizable. }
-
- SetRect(theWindRect, kReaderWindh, kReaderWindv, kReaderWindh, kReaderWindv);
- itsWindow.SetSizeRect(theWindRect);
-
- { To be able to hide the window, it must be non-modal. }
-
- itsWindow.SetModal(kModeless);
-
- gDecorator.PlaceNewWindow(itsWindow);
- gDecorator.CenterWindow(itsWindow);
-
- { Background picture. }
-
- new(thePicture);
- thePicture.IPicture(itsWindow, SELF, kReaderWindh, kReaderWindv, 0, 0, sizFIXEDSTICKY, sizFIXEDSTICKY);
- if gSystem.hasColorQD then begin
- thePicture.UsePICT(PICTReaderColour);
- end { if }
- else begin
- thePicture.UsePICT(PICTReaderBW);
- end; { else }
- thePicture.SetScaled(FALSE);
-
- { Text saying what file we are reading from. }
-
- new(theEditText);
- theEditText.IEditText(itsWindow, SELF, kReaderTextLenh, kReaderTextLenv, kReaderTextPosh, kReaderTextPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kReaderTextLenh);
- theEditText.Specify(kNotEditable, kNotSelectable, kNotStylable);
- theEditText.SetAlignCmd(cmdAlignLeft);
- theEditText.SetFontNumber(0); { System font, Chicago. }
- GetIndString(theReadingStr, STRlistAppMessages, kSTRAppReading);
- theEditText.SetTextString(Concat(theReadingStr, ' “', macSFReply.fName, '”.'));
-
- { Progress bar. }
-
- new(theProgBar);
- theProgBar.IProgressBar(itsWindow, SELF, kReaderProgBarLenh, kReaderProgBarLenv, kReaderProgBarPosh, kReaderProgBarPosv, sizFIXEDSTICKY, sizFIXEDSTICKY, kUseColor, kHorizontal, KNoShadow, FinderFillColor, FinderBackColor);
- itsProgBar := theProgBar;
-
- { Border for the progress bar. }
-
- new(theBorder);
- theBorder.IPaneBorder(kBorderFrame);
- theProgBar.SetBorder(theBorder);
-
- { Select the window to bring it to the front. }
-
- itsWindow.Select;
-
- { Until now, no updating has been done. }
- { We have to force one now, to correctly draw the picture. }
-
- itsWindow.Update;
- end; { BuildWindow }
-
- procedure HandleFailure (error: Integer; message: Longint);
-
- begin { HandleFailure }
- { Something failed here. Restore the resource, forget the level, }
- { then allow the exception to propagate. }
-
- ForgetObject(theList);
- ForgetObject(theLevel);
- itsFile.Close;
- UseResFile(theSavedRes);
- end; { HandleFailure }
-
- begin { OpenFile }
- new(theFile);
- theFile.IResFile;
- theFile.SFSpecify(macSFReply);
-
- itsFile := theFile; { For inherited methods. }
- itsShLevelsFile := theFile; { For our use. }
-
- BuildWindow;
-
- new(theList);
- theList.IList;
- theLevel := nil;
-
- { We know that the window has just been created, and hence that the }
- { progress bar is currently at 0 percent. }
-
- { Store the current resource file so that we can restore it after }
- { we are finished with the levels file. }
-
- theSavedRes := CurResFile;
-
- { Read each level from resource, and place in list. }
-
- CatchFailures(fi, HandleFailure);
-
- itsShLevelsFile.Open(fsRdPerm);
-
- { Assume numeric contiguity of levels, and load the number present. }
- { SetLEVL and SetBEST handle the cases for invalid resources. }
- theNumLevels := Count1Resources(kLEVLResType);
- for theCount := 1 to theNumLevels do begin
-
- new(theLevel);
- theLevel.SetLEVL(LEVLDefStart + theCount - 1);
-
- { We look at the best player resource here, so that }
- { we correctly link the level with the player. }
-
- theLevel.SetBEST(BESTDefStart + theCount - 1);
-
- theList.InsertAt(theLevel, theCount);
-
- itsProgBar.UpdateProgress(Integer(LongInt(theCount) * 100 div theNumLevels));
- end;
-
- itsShLevelsFile.Close;
-
- Success;
-
- UseResFile(theSavedRes);
-
- itsShApp.GameDirector.SetLevels(theList);
-
- { After setting levels, reselect the game director's window. Then hide our own window. }
- { This order is important! }
- { This is really a bit of trickery to ensure that the game director window is always foremost. }
- { Generally, one would expect that a document's window would be the active one after opening. }
-
- itsShApp.GameDirector.GetWindow.Select;
- itsWindow.Hide;
- end; { OpenFile }
-
-
- {****************************************************}
- {}
- { StoreBestPlayer }
- {}
- { Stores the specified best player to the levels file. }
- {}
- {****************************************************}
-
- procedure CShLevelsDoc.StoreBestPlayer (aLevelNum: LevelsRange; aPlayer: Str15; aMoves: Integer; aTime: LongInt);
-
- var
- theBEST: BESTtemplateH; { Handle to best player resource. }
-
- theSavedRes: Integer;
- fi: FailInfo;
-
- procedure HandleFailure (error: Integer; message: Longint);
-
- begin { HandleFailure }
- (* Something failed here. Restore the resource, *)
- (* forget the level, then allow the exception to propagate.*)
-
- { Does closing the file really help? }
-
- itsShLevelsFile.Close;
- UseResFile(theSavedRes);
- end; { HandleFailure }
-
- begin { StoreBestPlayer }
- theSavedRes := CurResFile;
-
- CatchFailures(fi, HandleFailure);
-
- itsShLevelsFile.Open(fsRdWrPerm);
-
- theBEST := BESTtemplateH(Get1Resource(kBESTResType, BESTDefStart + aLevelNum - 1));
-
- { We want to replace any existing resource of this type and ID. }
-
- if theBEST <> nil then begin
- HNoPurge(Handle(theBest));
-
- { Set the new best player for this level. }
- theBest^^.thePlayer := aPlayer;
- theBest^^.theMoves := aMoves;
- theBest^^.theTime := aTime;
-
- ChangedResource(Handle(theBest));
- FailResError;
- WriteResource(Handle(theBest));
-
- HPurge(Handle(theBest));
- end { if }
- else begin
-
- SetCriticalOperation(TRUE);
- theBest := BESTtemplateH(NewHandleCanFail(SizeOf(BESTtemplate)));
- FailNIL(theBest);
- SetCriticalOperation(FALSE);
-
- { Set the new best player for this level. }
- theBest^^.thePlayer := aPlayer;
- theBest^^.theMoves := aMoves;
- theBest^^.theTime := aTime;
-
- { Add it to the resource file. }
- AddResource(Handle(theBest), kBESTResType, BESTDefStart + aLevelNum - 1, '');
- FailResError;
- WriteResource(Handle(theBest));
-
- end; { else }
-
- itsShLevelsFile.Close;
-
- UseResFile(theSavedRes);
-
- Success;
- end; { StoreBestPlayer }
-
-
- {****************************************************}
- {}
- { ClearBestPlayers }
- {}
- { Clears the best players from the levels file. }
- {}
- {****************************************************}
-
- procedure CShLevelsDoc.ClearBestPlayers;
-
- var
- theBEST: BESTtemplateH; { Handle to best player resource. }
-
- theSavedRes: Integer;
- fi: FailInfo;
-
- procedure HandleFailure (error: Integer; message: Longint);
-
- begin { HandleFailure }
- (* Something failed here. Restore the resource, *)
- (* forget the level, then allow the exception to propagate.*)
-
- { Does closing the file really help? }
-
- itsShLevelsFile.Close;
- UseResFile(theSavedRes);
- end; { HandleFailure }
-
- begin { ClearBestPlayers }
- theSavedRes := CurResFile;
-
- CatchFailures(fi, HandleFailure);
-
- itsShLevelsFile.Open(fsRdWrPerm);
-
- { Can't use a for loop, because the act of removing a resource }
- { changes the internal indices (probably). }
- while Count1Resources(kBESTResType) > 0 do begin
- theBEST := BESTtemplateH(Get1IndResource(kBESTResType, 1));
- RmveResource(Handle(theBEST));
- ForgetHandle(theBEST); { Careful - don't use ForgetResource }
- end; { while }
-
- itsShLevelsFile.Close;
-
- UseResFile(theSavedRes);
-
- Success;
- end; { ClearBestPlayers }
-
-
- end. { CShLevelsDoc }